﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//回调函数
//⼀个通过函数指针调⽤的函数
//把函数的指针（地址）作为参数传递给另⼀个函数
//当这个指针被⽤来调⽤其所指向的函数时
//被调⽤的函数就是回调函数

//qsort：库函数 
//使用快速排序的思想实现的一个排序函数
//void*是无具体类型的指针，可接受任意类型的地址
//void*不能解引用操作，也不能+-整数


//qsort函数，可以排序任意类型的数据
//void qsort(void* base, //要排序的数据的起始位置
//		   size_t num, //待排序的数据元素的个数
//	       size_t size,//待排序的数据元素的大小（单位字节）
//	       int (*cmp)(const void* e1, const void*e2)//函数指针-比较函数（回调函数）
//);

//比较函数
//返回值 < 0, e1所指向元素会被排在e2所指向元素的左面
//返回值 > 0, e1所指向元素会被排在e2所指向元素的右面
//返回值 = 0，e1所指向元素与e2所指向元素的顺序不确定

//整数排序
//int cmp_int(const void* e1, const void* e2) {
//	return (*(int*)e1 - *(int*)e2);
//}
//
//int main() {
//	int arr[] = { 34,24,67,13,7,9,43,56 };
//	//排成升序
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	qsort(arr, sz, sizeof(arr[0]), cmp_int);
//	int i = 0;
//	for (i = 0; i < sz; i++) {
//		printf("%d ", arr[i]);
//	}
//	return 0;
//}
////浮点排序
//int cmp_double(const void* e1, const void* e2) {
//	if (*(double*)e1 == *(double*)e2) return 0;
//	else if (*(double*)e1 > *(double*)e2) return 1;
//	else return -1;
//
//}
//
//int main() {
//	double arr[] = { 2.2,2.4,2.5,2.1,2.0 };
//	//排成升序
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	qsort(arr, sz, sizeof(arr[0]), cmp_double);
//	int i = 0;
//	for (i = 0; i < sz; i++) {
//		printf("%f ", arr[i]);
//	}
//	return 0;
//}
//结构数据排序
//结构体
//struct Stu {
//	char name[20];
//	int age;
//};
////比较名字的比较函数
//int cmp_Stu_name(const void* e1, const void* e2) {
//	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
//}
////比较年龄的比较函数
//int cmp_Stu_age(const void* e1, const void* e2) {
//	return((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
//}
//
//void test() {
//	struct Stu s[] = { {"珠宝",18},{"李四",43},{"牛",24} };
//	int sz = sizeof(s) / sizeof(s[0]);
//	//qsort(s, sz, sizeof(s[0]), cmp_Stu_name);
//	qsort(s, sz, sizeof(s[0]), cmp_Stu_age);
//}
//
//int main() {
//	test();
//	return 0;
//}

//冒泡模拟实现qsort函数

int int_cmp(const void* p1, const void* p2)
{
	return (*(int*)p1 - *(int*)p2);
}
void _swap(void* p1, void* p2, int size)
{
	int i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char*)p1 + i);
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}
}

void bubble(void* base, int count, int size, int(*cmp)(void*, void*))
{
	int i = 0;
	int j = 0;
	//趟数
	for (i = 0; i < count - 1; i++)
	{	
		int flag = 1;//假设数组是排好序的
		//一趟冒泡排序的过程
		//i个已排好
		for (j = 0; j < count - i - 1; j++)
		{
			//cmp的两个参数传的是待比较的两个元素的地址
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) >0)
			{
				//交换
				_swap((char*)base + j * size, (char*)base + (j + 1) * size,size);
				flag = 0;
			}
		}
		if (flag == 1) {
			break;
		}
	}
}
int main()
{
	int arr[] = { 8, 6, 3, 5, };
	int i = 0;
	bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}
